package com.activenetwork.smlite.page.event.EventDetailView;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;


import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.activenetwork.custom.other.Checkbox;
import com.activenetwork.custom.other.XCheckbox;
import com.activenetwork.custom.uielement.UIElement;
import com.activenetwork.custom.uielement.decorate.InJson;
import com.activenetwork.schema.model.event.EventBasicType;
import com.activenetwork.smlite.page.generic.EventModelPage;
import com.activenetwork.util.DateUtil;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.WaitUtil;
import com.activenetwork.util.datepicker.DatePicker;
import com.activenetwork.util.dropdownmenu.DropdownMenu;
import com.activenetwork.util.dropdownmenu.TimeDropdownMenu;
import com.beust.jcommander.internal.Lists;

public class EventBasicSubview extends EventModelPage {
	
	@InJson
	private UIElement showHideBasicMsg;
	
	@InJson
	private UIElement eventTitle;
	
	@InJson
	private UIElement eventLocation;
	
	@InJson
	private UIElement addLocation;
	
	@InJson
	private UIElement locationName;
	
	@InJson
	private UIElement locationAddress;
	
	@InJson
	private UIElement locationAddressContinue;
	
	@InJson
	private UIElement locationCityRegion;
	
	@InJson
	private UIElement locationStateProvince;
	
	@InJson
	private UIElement locationPostalCode;
	
	@InJson
	private UIElement locationPrimary;
	
	@InJson
	private UIElement locatonCounty;
	
	@InJson
	private UIElement saveLocation;
	
	@InJson
	private UIElement cancelLocation;
	
	@InJson
	private UIElement eventCategory;
	
	@InJson
	private UIElement eventLengthSingleDay;
	
	@InJson
	private UIElement eventLengthMultiDay;
	
	@InJson
	private UIElement eventDate;
	
	@InJson
	private UIElement startTime;
	
	@InJson
	private UIElement endTime;
	
	@InJson
	private UIElement eventStartDate;
	
	@InJson
	private UIElement eventEndDate;
	
	@InJson
	private UIElement eventTag;
	
	@InJson
	private UIElement addTag;
	
	@InJson
	private UIElement tagName;
	
	@InJson
	private UIElement tagDesc;
	
	@InJson
	private UIElement saveTag;
	
	@InJson
	private UIElement cancelTag;
	
	@InJson
	private UIElement nextStep;
	
	@InJson
	private UIElement showHideTag;
	
	
	public EventBasicSubview showBasicMsg(){
		WebDriver driver = EnvContext.webDriverTL.get();
		WebElement helpDiv = driver.findElement(By.cssSelector(".autotest-html-eventbasicsubview #nexus-basic-help"));
		String value = helpDiv.getAttribute("class").trim();
		if(StringUtils.equalsIgnoreCase(value, "collapse")){
			showHideBasicMsg.click();
			new WaitUtil().wait(500);
			return PageLoader.load(EventBasicSubview.class);
		}else{
			return this;
		}
	}
	
	public EventBasicSubview hideBasicMsg(){
		WebDriver driver = EnvContext.webDriverTL.get();
		WebElement helpDiv = driver.findElement(By.cssSelector(".autotest-html-eventbasicsubview #nexus-basic-help"));
		String value = helpDiv.getAttribute("class").trim();
		if(StringUtils.equalsIgnoreCase(value, "collapse in") || StringUtils.equalsIgnoreCase(value, "in collapse")){
			showHideBasicMsg.click();
			new WaitUtil().wait(500);
			return PageLoader.load(EventBasicSubview.class);
		}else{
			return this;
		}
	}
	
	/**
	 * Set event title with event data object
	 * @param eventBasic
	 */
	public void setEventTitle(EventBasicType eventBasic){
		eventTitle.clear();
		eventTitle.sendKeys(eventBasic.getTitle());
	}
	
	
	/**
	 * set event title with string
	 * @param titlename
	 */
	public void setEventTitle(String titleName){
		eventTitle.clear();
		eventTitle.sendKeys(titleName);
	}
	
	/**
	 * get event title value
	 * @return
	 */
	public String getEventTitle(){
		String titlename=eventTitle.getAttribute("value");
		return titlename;
	}
	
	/**
	 * AJAX to get existing location and select it
	 * @param location
	 * @return
	 */
	public EventBasicSubview selectEventLocationAJAX(EventBasicType.Location location){
		if(location == null){
			return this;
		}
		
		eventLocation.clear();
		eventLocation.sendKeys(location.getLocationName());
		
		// waiting for AJAX loading, progress bar displaying
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		// sometimes, progress bar is gone but the suggestion list still updates
		// we need to wait until suggest list is ready
		WaitUtil waitUtil = new WaitUtil(500);
		waitUtil.waiting();
		
		// Get all possible locations from suggestion list
		By by = By.cssSelector(".autotest-lookup-EventBasicSubview-event-locationref-displaystring div.nexus-lookup div.dropdown ul>li");
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> existingLocations = driver.findElements(by);
		//loop to find the specific one
		for(WebElement elc : existingLocations){
			WebElement link = elc.findElement(By.xpath("./a"));
			if(StringUtils.equalsIgnoreCase(link.getText().trim(), location.getLocationName())){
				link.click();
				return instance;
			}
		}
		
		throw new RuntimeException("No matched existing location record found for location:" + location.getLocationName());
			
	}
	/**
	 * AJAX to get the existing location and select the specific one
	 * @param searchContent
	 * @param address
	 * @return
	 */
	public EventBasicSubview selectEventLocationAJAX(String searchContent, int address){
		eventLocation.clear();
		eventLocation.sendKeys(searchContent);
		
		// waiting for AJAX loading, progress bar displaying
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		// sometimes, progress bar is gone but the suggestion list still updates
		// we need to wait until suggest list is ready
		WaitUtil waitUtil = new WaitUtil(500);
		waitUtil.waiting();
		
		// Get all possible locations from suggestion list
		By by = By.cssSelector(".autotest-lookup-EventBasicSubview-event-locationref-displaystring div.nexus-lookup div.dropdown ul>li");
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> existingLocations = driver.findElements(by);
		
		// address is bigger than pop-up rows
		if(address > existingLocations.size()){
			throw new RuntimeException("Total existing location rows are insufficient");
		}
		
		// if existing location not found
		if(existingLocations.size()==1){
			String id = existingLocations.get(0).getAttribute("data-lookupvalue-identifier").trim();
			if(StringUtils.equalsIgnoreCase(id, "matchnotfound")){
				throw new RuntimeException("No Existing location record found");
			}
		}
		
		// select the specific one
		WebElement link = existingLocations.get(address-1).findElement(By.xpath("./a"));
		link.click();
		
		return instance;
	}
	/**
	 *  AJAX to get existing tag and select it
	 * @param tag
	 * @return
	 */
	public EventBasicSubview selectEventTagAJAX(EventBasicType.Tag tag){
		eventTag.clear();
		eventTag.sendKeys(tag.getTagName());
		// waiting for AJAX loading, progress bar displaying
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		// sometimes, progress bar is gone but the suggestion list still updates
		// we need to wait until suggest list is ready
		WaitUtil waitUtil = new WaitUtil(500);
		waitUtil.waiting();
		
		// Get all possible tags from suggestion list
		By by = By.cssSelector(".autotest-lookup-EventBasicSubview-event-tagsref div.nexus-lookup div.dropdown ul>li");
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> existingTags = driver.findElements(by);
		//loop to find the specific one
		for(WebElement elc : existingTags){
			WebElement link = elc.findElement(By.xpath("./a"));
			if(StringUtils.equalsIgnoreCase(link.getText().trim(), tag.getTagName())){
				link.click();
				return instance;
			}
		}

		throw new RuntimeException("No matched existing tags record found for tag:" + tag.getTagName());
	}
	/**
	 * AJAX to get the existing tag and select the specific one
	 * @param searchContent
	 * @param tag
	 * @return
	 */
	public EventBasicSubview selectEventTagAJAX(String searchContent, int tag){

		WebDriver driver = EnvContext.webDriverTL.get();
		
		eventTag.sendKeys(searchContent);
		// waiting for AJAX loading, progress bar displaying
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		// sometimes, progress bar is gone but the suggestion list still updates
		// we need to wait until suggest list is ready
		WaitUtil waitUtil = new WaitUtil(500);
		waitUtil.waiting();
		// Get all possible tags from suggestion list
		By by = By.cssSelector(".autotest-lookup-EventBasicSubview-event-tagsref div.nexus-lookup div.dropdown ul>li");
//		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> existingTags = driver.findElements(by);
		
		// address is bigger than pop-up rows
		if(tag > existingTags.size()){
			throw new RuntimeException("Total existing tag rows are insufficient");
		}
		
		// if not found
		if(existingTags.size()==1){
			String id = existingTags.get(0).getAttribute("data-lookupvalue-identifier").trim();
			if(StringUtils.equalsIgnoreCase(id, "matchnotfound")){
				throw new RuntimeException("No Existing location tag found");
			}
		}
		
		WebElement link = existingTags.get(tag-1).findElement(By.xpath("./a"));
		link.click();
		
		return instance;
	}
	/**
	 * Set event location by adding a new one
	 * @param eventBasic
	 */
	public void setEventLocation(EventBasicType eventBasic){
		EventBasicType.Location location = eventBasic.getLocation();
		
		addLocation.click();
		new WaitUtil().wait(500);
		
		locationName.clear();locationName.sendKeys(location.getLocationName());
		if(location.getAddress() != null){
			locationAddress.clear();
			locationAddress.sendKeys(location.getAddress());
		}
		if(location.getAddressContinue() != null){
			locationAddressContinue.clear();
			locationAddressContinue.sendKeys(location.getAddressContinue());
		}
		if(location.getCityRegion() != null){
			locationCityRegion.clear();
			locationCityRegion.sendKeys(location.getCityRegion());
		}
		if(location.getStateProvince() != null){
			locationStateProvince.clear();
			locationStateProvince.sendKeys(location.getStateProvince());
			
		}
		if(location.getPostalCode() != null){
			locationPostalCode.clear();
			locationPostalCode.sendKeys(location.getPostalCode());
		}
		if(location.getCounty() != null){
			locatonCounty.clear();
			locatonCounty.sendKeys(location.getCounty());
			locatonCounty.sendKeys(Keys.ENTER);
		}
		if(location.isPrivate() != null){
			Checkbox checkbox = new XCheckbox(locationPrimary);
			if(location.isPrivate()){
				checkbox.checkON();
			}else{
				checkbox.checkOFF();
			}
		}
		
	}
	/**
	 * Save the input location information
	 * @return
	 */
	public EventBasicSubview saveLocation(){
		saveLocation.click();
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Cancel the input location information
	 * @return
	 */
	public EventBasicSubview cancelLocation(){
		cancelLocation.click();
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Select the event category dropdown
	 * @param eventBasic
	 */
	public void setEventCategory(EventBasicType eventBasic){
		if(eventBasic.getCategory() != null){
			eventCategory.clear();
			eventCategory.sendKeys(eventBasic.getCategory());
			eventCategory.sendKeys(Keys.ENTER);
		}
	}
	/**
	 * Select the event category dropdown with UI operation
	 * @param eventBasic
	 */
	public void setEventCategoryUI(EventBasicType eventBasic){
		if(eventBasic.getCategory() != null){
			DropdownMenu eventCategoryDropdown = new DropdownMenu(eventCategory);
			eventCategoryDropdown.select(eventBasic.getCategory());
		}
	}
	/**
	 * Set event date, start time and end time by selenium API
	 * @param eventBasic
	 * @return
	 */
	public EventBasicSubview setSingleDate(EventBasicType eventBasic){
		eventLengthSingleDay.click();
		new WaitUtil().wait(500);
		
		EventBasicType.Length.OneDay day = eventBasic.getLength().getOneDay();
		 
		// event date
		if(day.getEventDate() != null){
			String date = new SimpleDateFormat("M/d/yyyy").format(day.getEventDate().toGregorianCalendar().getTime());
			eventDate.clear();
			eventDate.sendKeys(date);
		}
		
		// start time
		if(day.getStartTime() != null){
			String start_hour = String.valueOf(day.getStartTime().getHour());
			String start_min = String.valueOf(day.getStartTime().getMinute());
			startTime.clear();
			startTime.sendKeys(start_hour + ":" + start_min);
			startTime.sendKeys(Keys.ESCAPE);
		}
		
		// end time
		if(day.getEndTime() != null){
			String end_hour = String.valueOf(day.getEndTime().getHour());
			String end_min = String.valueOf(day.getEndTime().getMinute());
			endTime.clear();
			endTime.sendKeys(end_hour + ":" + end_min);
			endTime.sendKeys(Keys.ESCAPE);	
		}
		
		return PageLoader.load(EventBasicSubview.class);
		
	}
	/**
	 * Set event date, start time and end time by UI operation
	 * @param eventBasic
	 * @return
	 */
	public EventBasicSubview setSingleDateUI(EventBasicType eventBasic){
		eventLengthSingleDay.click();
		new WaitUtil().wait(500);
		
		EventBasicType.Length.OneDay day = eventBasic.getLength().getOneDay();
		
		// event date
		if(day.getEventDate() != null){
			Calendar cal = day.getEventDate().toGregorianCalendar();
			DatePicker dataPicker = new DatePicker(eventDate);
			dataPicker.pick(cal);
		}
		
		// start time
		if(day.getStartTime() != null){
			DropdownMenu startTimeDropdown = new TimeDropdownMenu(startTime);
			startTimeDropdown.select(DateUtil.toTimeOption(day.getStartTime()));
		}
		
		// end time
		if(day.getEndTime() != null){
			DropdownMenu endTimeDropdown = new TimeDropdownMenu(endTime);
			endTimeDropdown.select(DateUtil.toTimeOption(day.getEndTime()));
		}
		
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Set multiple day mode: event start date and event end date by selenium API
	 * @param eventBasic
	 * @return
	 */
	public EventBasicSubview setMultiDate(EventBasicType eventBasic){
		eventLengthMultiDay.click();
		new WaitUtil().wait(500);
		
		EventBasicType.Length.MultiDay day = eventBasic.getLength().getMultiDay();
		 
		// start date
		if(day.getStartDate() != null){
			String startDate = new SimpleDateFormat("M/d/yyyy").format(day.getStartDate().toGregorianCalendar().getTime());
			eventStartDate.clear();
			eventStartDate.sendKeys(startDate);
		}
		
		// end date
		if(day.getEndDate() != null){
			String endDate = new SimpleDateFormat("M/d/yyyy").format(day.getEndDate().toGregorianCalendar().getTime());
			eventEndDate.clear();
			eventEndDate.sendKeys(endDate);
		}

		return PageLoader.load(EventBasicSubview.class);
		
	}
	/**
	 *  Set multiple day mode: event start date and event end date by UI operation
	 * @param eventBasic
	 * @return
	 */
	public EventBasicSubview setMultiDateUI(EventBasicType eventBasic){
		eventLengthMultiDay.click();
		new WaitUtil().wait(500);
		
		EventBasicType.Length.MultiDay day = eventBasic.getLength().getMultiDay();
		// start date
		if(day.getStartDate() != null){
			Calendar startCal = day.getStartDate().toGregorianCalendar();
			DatePicker startDatePicker = new DatePicker(eventStartDate);
			startDatePicker.pick(startCal);
		}
		// end date
		if(day.getEndDate() != null){
			Calendar endCal = day.getEndDate().toGregorianCalendar();
			DatePicker endDatePicker = new DatePicker(eventEndDate);
			endDatePicker.pick(endCal);
		}
	
		return PageLoader.load(EventBasicSubview.class);
	}
	
	/**
	 * Delegate of setting new tag information
	 * @param tag
	 * @return
	 */
	public EventBasicSubview setTag(EventBasicType.Tag tag){
		addTag.click();
		new WaitUtil().wait(1000);
		
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		return instance.setTagAction(tag);
	}
	/**
	 * Create a new tag and set name / desc
	 * @param tag
	 * @return
	 */
	private EventBasicSubview setTagAction(EventBasicType.Tag tag){
		tagName.clear();
		tagName.sendKeys(tag.getTagName());
		
		if(tag.getTagDesc() != null){
			tagDesc.clear();
			tagDesc.sendKeys(tag.getTagDesc());
		}
		
//		if(tag.isPrivate() != null){
//			Checkbox primaryCheck = new XCheckbox(tagPrimary);
//			if(tag.isPrivate()){
//				primaryCheck.checkON();
//			}else{
//				primaryCheck.checkOFF();
//			}
//		}
		
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Save the new tag
	 * @return
	 */
	public EventBasicSubview saveTag(){
		saveTag.click();
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Cancel saving new tag
	 * @return
	 */
	public EventBasicSubview cancelTag(){
		cancelTag.click();
		return PageLoader.load(EventBasicSubview.class);
	}
	
	private enum NextPage{
		attendeeDirectories, labelBadage, customReport, email, kiosk, mobile, 
		registrationForm, reports, socialMedia, sourcing, surveys, themedesigner,
		website
	}
	
	/**
	 * Click go sourcing button to end event creation
	 * @return
	 */
	public EventSourceSubview nextStep() throws RuntimeException{

		NextPage nextpage = null;
		
		WaitUtil waitUtil = new WaitUtil(1500);
		waitUtil.waiting();
		
		// judge next page object since different choice of components activates
		// different next page
		String nextPageName = nextStep.findElement(By.xpath(".//span")).getText().trim();
		if(StringUtils.equalsIgnoreCase(nextPageName, "Sourcing")){
			nextpage = NextPage.sourcing;
		}else if(StringUtils.equalsIgnoreCase(nextPageName, "Registration Form")){
			nextpage = NextPage.registrationForm;
		}else if(StringUtils.equalsIgnoreCase(nextPageName, "Social")){
			nextpage = NextPage.socialMedia;
		}else if(StringUtils.equalsIgnoreCase(nextPageName, "Website")){
			nextpage = NextPage.website;
		}else if(StringUtils.equalsIgnoreCase(nextPageName, "Email")){
			nextpage = NextPage.email;
		}else if(StringUtils.equalsIgnoreCase(nextPageName, "Directories")){
			nextpage = NextPage.attendeeDirectories;
		}
		
		// find the right arrow icon
		nextStep.findElement(By.xpath(".//i[@class='icon-arrow-right']")).click();
		
		if(nextpage == NextPage.sourcing){
			return PageLoader.load(EventSourceSubview.class);
		}else if(nextpage == NextPage.registrationForm){
			throw new RuntimeException("Current version does not support next page to be registration form");
		}else if(nextpage == NextPage.socialMedia){
			throw new RuntimeException("Current version does not support next page to be social media");
		}else if(nextpage == NextPage.website){
			throw new RuntimeException("Current version does not support next page to be website");
		}else if(nextpage == NextPage.email){
			throw new RuntimeException("Current version does not support next page to be email");
		}else if(nextpage == NextPage.attendeeDirectories){
			throw new RuntimeException("Current version does not support next page to be attendee directories");
		}else{
			throw new RuntimeException("Unknown next step");
		}
		
	}
	
	/**
	 * Select the components of one event
	 * @param components
	 * @return
	 */
	public EventBasicSubview selectComponents(EventBasicType.Components components){
		EventComponents eventComponents = PageLoader.load(EventComponents.class);
		WaitUtil waitUtil = new WaitUtil();
		waitUtil.wait(2000);
		eventComponents = eventComponents.sourcing(components);
		eventComponents = eventComponents.socialMedia(components);
		eventComponents = eventComponents.website(components);
		eventComponents = eventComponents.email(components);
		eventComponents = eventComponents.attendeeDirectories(components);
		eventComponents = eventComponents.registrationForm(components);
		eventComponents = eventComponents.themeDesigner(components);
		eventComponents = eventComponents.mobile(components);
		eventComponents = eventComponents.badgeLabel(components);
		eventComponents = eventComponents.kiosk(components);
		eventComponents = eventComponents.reports(components);
		eventComponents = eventComponents.customReport(components);
		eventComponents = eventComponents.surveys(components);
		return PageLoader.load(EventBasicSubview.class);
	}
	
	
	
	public List<String> getTagName(){
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> tags = driver.findElements(By.cssSelector(".autotest-lookup-EventBasicSubview-event-tagsref .nexus-lookup .btn.btn-small"));
		List<String> names = Lists.newArrayList();
		for(WebElement tag : tags){
			names.add(tag.getText().trim());
		}
		
		return names;
	}
	
	/**
	 * Remove one the existing tags of an event
	 * @return
	 */
	public EventBasicSubview removeTag(){
		WebDriver driver = EnvContext.webDriverTL.get();
		By removeIconBy = By.cssSelector("div.control-group.ae-tagref-lookup div.nexus-lookup a>i.icon-remove");
		List<WebElement> removeIconElement= driver.findElements(removeIconBy);
		if(removeIconElement.size() > 0){
			removeIconElement.get(0).click();
			return PageLoader.load(EventBasicSubview.class);
		}else{
			throw new RuntimeException("No existing tag now");
		}
		
	}
	/**
	 * Remove all the existing tags on an event
	 * @return
	 */
	public EventBasicSubview removeAllTag(){
		EventBasicSubview instance = PageLoader.load(EventBasicSubview.class);
		while(true){
			try{
				instance = instance.removeTag();
			}catch(RuntimeException e){
				break;
			}
		}
		return instance;
	}
	
	/**
	 * Click icon to show event tag
	 * @return
	 */
	public EventBasicSubview showEventTag(){
		WebElement span = eventTag.findElement(By.xpath("./ancestor::span[contains(@class,'nexus-section-body')]"));
		String status = span.getAttribute("class").trim();
		if(StringUtils.containsIgnoreCase(status, "hide")){
			showHideTag.click();
			new WaitUtil().wait(1000);
		}
		return PageLoader.load(EventBasicSubview.class);
	}
	/**
	 * Click icon to hide event tag
	 * @return
	 */
	public EventBasicSubview hideEventTag(){
		WebElement span = eventTag.findElement(By.xpath("./ancestor::span[contains(@class,'nexus-section-body')]"));
		String status = span.getAttribute("class").trim();
		if(!StringUtils.containsIgnoreCase(status, "hide")){
			showHideTag.click();
		}
		return PageLoader.load(EventBasicSubview.class);
	}

}
